package org.opens.configure;

import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.AsyncResult;
import org.springframework.stereotype.Component;
import org.springframework.util.concurrent.ListenableFuture;

import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

@Component
public class CountNumber {

    /**
     * 说明:
     *      1. 该注解还有一个参数，通过Bean名称来指定调用的线程池-比如上例中设置的线程池参数不满足业务需求，可以另外定义合适的线程池，
     *         调用时指明使用这个线程池-缺省时springboot会优先使用名称为'taskExecutor'的线程池，如果没有找到，才会使用其他类型为TaskExecutor或其子类的线程池。
     *      2. 也就是说如果给@Async指定了value的值, 则spring boot会优先去根据value指定的名称去匹配bean, 如果没有找到, 才会去匹配类型为TaskExecutor或其子类的线程池。
     */
    @Async
    public void printNumbser() {
        for(int i = 0; i < 10; i++) {
            System.out.println(i);
        }
    }

    /**
     * 说明:
     *      1. 其实AsyncResult就是Future对象的二次封装, 可以通过get来调用这个线程的执行结果.
     * @param name
     * @return
     */
    @Async
    public ListenableFuture<String> sayHello(String name) {
        String res = name + ":Hello World!";
        return new AsyncResult<>(res);
    }

    public static void main(String[] args) throws InterruptedException, ExecutionException, TimeoutException {
        ListenableFuture<String> result = new AsyncResult<>(getStr());
        System.out.println(result.get(1, TimeUnit.SECONDS));
    }

    public static String getStr() {
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return "s1";
    }

}
